function Promise(executor) {
    
    let _this = this

    // 有三个状态值 pending resolved/fulfilled rejected
    this.state = 'pending'

    // 成功的结果
    this.value = undefined

    // 失败的原因
    this.reason = undefined

    // 调用 then 方法的时候，如果是在一个异步任务中调用 resolve 那时的 state 还没有改变，不会输出值，我们可以使用订阅器的方式来处理，当异步执行后处理

    // 保存成功的回调
    this.onResolvedCallbacks = []

    // 保存失败的回调
    this.onRejectedCallbacks = []

    // 让其处理器函数立即执行, Promise 会接收一个处理器函数，进来的时候会立即执行
    try {
        executor(resolve, reject)
    } catch (e) {
        reject()
    }

    // ECMA 中规定，只有在状态为 pending 的时候才能够进行修该，并且一旦修该就不能再对其进行修改
    function resolve(value) {
        if (_this.state === 'pending') {
            _this.value = value
            // 遍历执行成功的回调
            _this.onResolvedCallbacks.forEach(cb => cb(value))
            _this.state = 'resolved'
        }
    }

    function reject(reason) {
        if (_this.state === 'pending') {
            _this.reason = reason
            // 遍历执行失败的回调
            _this.onRejectedCallbacks.forEach(cb => cb(reason))
            _this.state = 'rejected'
        }
    }
}
Promise.prototype.then = function (onFulfilled, onRejected) {
    // 如果then方法没有传入任何回调，则继续向下传递(值穿透)
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
    onRejected = typeof onRejected === 'function' ? onFulfilled : err => { throw err }

    // then 方法最后都会返回一个新的 Promise 对象，所以可以创建一个新的promise 
    const promise2 = new Promise((resolve, reject) => {
        // 用来处理异步任务的，当返回的值是pending的时候，说明 resolve 函数可能是在一个异步处理器中，使用订阅发布的模式（旁观者模式）对这个函数进行处理
        if (this.state === 'pending') { // 这个方法中描述的都是异步处理的一些方法
            this.onResolvedCallbacks.push(() => {
                // 使用queueMicrotask实现微任务
                queueMicrotask(() => {
                    try {
                        const x = onFulfilled(this.value)
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (err) {
                        reject(err)
                    }
                })

            })
            // 将失败的回调push到队列中
            this.onRejectedCallbacks.push(() => {
                queueMicrotask(() => {
                    try {
                        const x = onRejected(this.reason)
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (err) {
                        reject(err)
                    }
                })
            })
        }

        // resolve/reject 在同步中执行
        if (this.state === 'resolved') {
            queueMicrotask(() => {
                try {
                    const x = onFulfilled(this.value)
                    resolvePromise(promise2, x, resolve, reject)
                } catch (err) {
                    reject(err)
                }
            })
        }
        if (this.state === 'rejected') {
            queueMicrotask(() => {
                try {
                    const x = onRejected(this.reason)
                    resolvePromise(promise2, x, resolve, reject)
                } catch (err) {
                    reject(err)
                }
            })
        }
    })
    return promise2
}

// catch原型方法
Promise.prototype.catch = function (onRejected) {
    // 直接执行then方法，onFulfilled为null，传入onRejected
    return this.then(null, onRejected)
}

// resolve方法
Promise.resolve = function (val) {
    // 直接抛出一个成功状态的Promise
    return new Promise((resolve, reject) => {
        resolve(val)
    })
}

// reject方法
Promise.reject = function (val) {
    // 直接抛出一个拒绝状态的Promise
    return new Promise((resolve, reject) => {
        reject(val)
    })
}

// race方法
Promise.race = function (promises) {
    // return一个Promise
    return new Promise((resolve, reject) => {
        // 遍历执行promises
        for (let i = 0; i < promises.length; i++) {
            // then只要接收到状态改变，直接抛出
            promises[i].then(resolve, reject)
        }
    })
}

// all方法
Promise.all = function (arr) {
    // 只有一个目的 获取到所有的promise，都执行then，把结果放到数组，一起返回
    // 递归实现和遍历实现都可以

    // 用于存放每次执行后返回结果
    let aResult = []
    return new Promise(function (resolve, reject) {
        let i = 0
        // 开始逐次执行数组中的函数(重要)
        next()
        function next() {
            arr[i].then(function (res) {
                // 存储每次得到的结果
                aResult.push(res)
                i++
                if (i >= arr.length) {
                    // 如果函数数组中的函数都执行完，便resolve
                    resolve(aResult)
                } else {
                    next()
                }
            })
        }
    })
}
// 处理根据上一个then方法的返回值来生成新Promise对象

/**
 * 解析then返回值与新promise对象
 * @param {*} promise2 
 * @param {*} x  上一个 then 的返回值
 * @param {function} resolve resolve promise2 处理器函数的 resolve 
 * @param {function} reject reject promise2 处理器函数的 reject
 */
function resolvePromise(promise2, x, resolve, reject) {
    // 解决循环引用报错
    if (promise2 === x) {
        // reject报错
        reject(new TypeError("请避免Promise循环引用"))
    }
    // 定义状态-防止多次调用
    let called
    // x不是null 且x是对象或函数
    if (x != null && (typeof x === "object" || typeof x === "function")) {
        try {
            // 拿到x的then方法
            let then = x.then
            // 如果then是函数，就默认是promise
            if (typeof then === "function") {
                // 执行then 使用call传递this 第一个参数是this 后面是成功的回调 和 失败的回调
                then.call(
                    x,
                    y => {
                        // 成功和失败只能调用一个
                        if (called) return
                        called = true
                        // 防止用户在resolve的时候传入Promise，递归调用
                        resolvePromise(promise2, y, resolve, reject)
                    },
                    err => {
                        // 成功和失败只能调用一个
                        if (called) return
                        called = true
                        reject(err)
                    }
                )
            } else {
                resolve(x)
            }
        } catch (e) {
            if (called) return
            called = true
            reject(e)
        }
    } else {
        resolve(x)
    }
}



// then 方法的实现

/**
首先then 方法必须返回一个 promise 对象(划重点)
如果then方法中返回的是一个普通值(如Number、String等)就使用此值包装成一个新的Promise对象返回
如果then方法中没有return语句，就返回一个用Undefined包装的Promise对象
如果then方法中出现异常，则调用失败态方法(reject)跳转到下一个then的onRejected
如果then方法没有传入任何回调，则继续向下传递(值穿透)
如果then方法中返回了一个Promise对象，那就以这个对象为准，返回它的结果
 * 
 */

const p = new Promise((resolve, reject) => {
    resolve(2)
})

// console.log(p);
console.log(p.then());
// p.then(res=>{
//     console.log(res);
//     return res
// },err => {
//     console.log(err);
// }).then().then().then(res=>{
//     console.log("res",res);
// })
